`timescale 1ns/1ps

module tb_interrupt_controller;

  reg         sys_clk, sys_resetn;
  reg         cpu_clk, cpu_resetn;
  reg  [31:0] int_en, int_edge, int_pol, int_in, int_clr;
  wire [31:0] int_state;
  wire        int_out;

  // 实例化待测模块
  interrupt_controller uut (
    .sys_clk(sys_clk),
    .sys_resetn(sys_resetn),
    .cpu_clk(cpu_clk),
    .cpu_resetn(cpu_resetn),
    .int_en(int_en),
    .int_edge(int_edge),
    .int_pol(int_pol),
    .int_in(int_in),
    .int_clr(int_clr),
    .int_state(int_state),
    .int_out(int_out)
  );

  // 50MHz时钟
  initial begin
    sys_clk = 0;
    forever #10 sys_clk = ~sys_clk;
  end

  initial begin
    cpu_clk = 0;
    forever #12 cpu_clk = ~cpu_clk;
  end

  initial begin
    sys_resetn = 0;
    cpu_resetn = 0;
    int_en     = 32'b0;
    int_edge   = 32'b0;
    int_pol    = 32'b0;
    int_in     = 32'b0;
    int_clr    = 32'b0;
    #30;
    sys_resetn = 1;
    cpu_resetn = 1;
    #30;

    // 配置通道0为边沿上升沿触发，通道1为电平高有效
    int_en   = 32'b11;     // 0,1使能
    int_edge = 32'b01;     // 通道0边沿, 通道1电平
    int_pol  = 32'b11;     // 都为高有效/上升沿

    // 产生通道0上升沿
    #25; int_in[0] = 1'b1;
    #25; int_in[0] = 1'b0;
    #25; int_in[0] = 1'b1; // 再次上升沿

    // 产生通道1高电平
    #10; int_in[1] = 1'b1;
    #40; int_in[1] = 1'b0;

    // 清除通道0中断
    #10; int_clr[0] = 1'b1;
    #10; int_clr[0] = 1'b0;

    // 测试下降沿触发，通道2
    int_en[2]   = 1'b1;
    int_edge[2] = 1'b1;
    int_pol[2]  = 1'b0; // 下降沿
    #10; int_in[2] = 1'b1;
    #25; int_in[2] = 1'b0; // 下降沿产生

    // 清除通道2中断
    #10; int_clr[2] = 1'b1;
    #10; int_clr[2] = 1'b0;

    // END
    #100;
    $stop;
  end

  // 波形输出
  initial begin
    $dumpfile("tb_interrupt_controller.vcd");
    $dumpvars(0, tb_interrupt_controller);
  end

endmodule